#include "at_command.h"

bool AT_Command_Processor(String cmd, at_cmd_parse_t *parse_cmd)
{
	String param_buf;
	uint16_t start;
	uint16_t segment;

	start = cmd.indexOf("AT+");
	if (start >= 0)
	{
		start += 3; // 跳过“AT+”这三个字符
		if (cmd.indexOf("?=", start) >= 0)
		{
			segment = cmd.indexOf("?=", start);
			parse_cmd->mode = AT_CMD_MODE_TESTING;
			parse_cmd->cmd_name = cmd.substring(start, segment); // AT+cmd_name?=param_buf，这里截取的是cmd_name
			start = segment + 2;
			param_buf = cmd.substring(start, cmd.length()); // AT+cmd_name?=param_buf，这里截取的是param_buf
			if (AT_Command_str2param(param_buf, &parse_cmd->cmd_param) == false)
			{
				parse_cmd->mode = AT_CMD_MODE_INVALID;
				return false;
			}
		}
		else if (cmd.indexOf("=", start) >= 0)
		{
			segment = cmd.indexOf("=", start);
			parse_cmd->mode = AT_CMD_MODE_EXECUTION;
			parse_cmd->cmd_name = cmd.substring(start, segment); // AT+cmd_name=param_buf，这里截取的是cmd_name
			start = segment + 1;
			param_buf = cmd.substring(start, cmd.length()); // AT+cmd_name=param_buf，这里截取的是param_buf
			if (AT_Command_str2param(param_buf, &parse_cmd->cmd_param) == false)
			{
				parse_cmd->mode = AT_CMD_MODE_INVALID;
				return false;
			}
		}
		else if (cmd.indexOf("?", start) > 0)
		{
			segment = cmd.indexOf("?", start);
			parse_cmd->mode = AT_CMD_MODE_READ;
			parse_cmd->cmd_name = cmd.substring(start, segment); // AT+cmd_name?，这里截取的是cmd_name
		}
		else
		{
			parse_cmd->mode = AT_CMD_MODE_ACTIVE; // AT+cmd_name，这里截取的是cmd_name
			parse_cmd->cmd_name = cmd.substring(start, cmd.length());
		}
	}
	else
	{
		start = cmd.indexOf("AT");
		if (start >= 0) // AT
		{
			parse_cmd->mode = AT_CMD_MODE_ACTIVE;
			parse_cmd->cmd_name = cmd;
		}
		else
		{
			parse_cmd->mode = AT_CMD_MODE_INVALID;
			parse_cmd->cmd_name = cmd;
		}
	}
	return true;
}

bool AT_Command_str2param(String param, at_cmd_param_t *cmd_param)
{
	String paramPart;
	String split = ","; // 分割符
	double value;
	uint16_t start = 0;
	uint16_t segment = 0;
	uint16_t temp = 0;
	uint16_t i;

	cmd_param->param_count = 0;
	for (i = 0; i < param_count_max; i++)
	{
		cmd_param->param_types[i] = NOS_NUM;
		cmd_param->param_double[i] = 0;
		cmd_param->param_string[i] = "\0";
	}

	for (i = 0; i < param_count_max; i++)
	{
		segment = param.indexOf(split, start); // 判断是否为最后一个分割符
		if (segment >= 0)
		{
			// 区分是字符串类型还是数字类型
			if (param[start] == '\"')
			{
				// 找到字符串末尾的双引号
				temp = param.indexOf('\"', start + 1);
				if (temp >= 0)
				{
					cmd_param->param_string[i] = param.substring(start + 1, temp);
					cmd_param->param_count = i + 1;
					cmd_param->param_types[i] = NOS_STR;
					// 如果字符串中间有分割符，这个分割符属于字符串的，因此分割符地址有误，需要从末尾双引号后再找分割符
					if (temp > segment)
					{
						segment = param.indexOf(split, temp);
					}
				}
				else
				{
					return false;
				}
			}
			else
			{
				// 这里是数字类型处理
				paramPart = param.substring(start, segment);
				str2d(paramPart, &value);
				cmd_param->param_double[i] = value;
				cmd_param->param_count = i + 1;
				cmd_param->param_types[i] = NOS_NUM;
			}
			start = segment + 1;
		}
		else
		{
			if (param[start] == '\"')
			{
				temp = param.indexOf('\"', start + 1);
				if (temp >= 0)
				{
					cmd_param->param_string[i] = param.substring(start + 1, temp);
					cmd_param->param_count = i + 1;
					cmd_param->param_types[i] = NOS_STR;
				}
				else
				{
					return false;
				}
			}
			else
			{
				paramPart = param.substring(start, param.length());
				str2d(paramPart, &value);
				cmd_param->param_double[i] = value;
				cmd_param->param_count = i + 1;
				cmd_param->param_types[i] = NOS_NUM;
			}
			return true;
		}
	}
	return true;
}

void str2d(String str, double *value)
{
	if (str.indexOf('.') >= 0)
	{
		*value = str.toDouble();
	}
	else if ((str.indexOf("0x") >= 0) || (str.indexOf("0X") >= 0))
	{
		*value = htoi(str);
	}
	else if ((str.indexOf("0b") >= 0) || (str.indexOf("0B") >= 0))
	{
		*value = btoi(str);
	}
	else
	{
		*value = str.toInt();
	}
}

double htoi(String s)
{
	int i;
	double n = 0;
	if ((s[0] == '0') && (s[1] == 'x' || s[1] == 'X'))
	{
		i = 2;
	}
	else
	{
		i = 0;
	}
	for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'f') || (s[i] >= 'A' && s[i] <= 'F'); ++i)
	{
		if (tolower(s[i]) > '9')
		{
			n = 16 * n + (10 + tolower(s[i]) - 'a');
		}
		else
		{
			n = 16 * n + (tolower(s[i]) - '0');
		}
	}
	return n;
}

double btoi(String s)
{
	int i;
	double n = 0;
	if ((s[0] == '0') && (s[1] == 'b' || s[1] == 'B'))
	{
		i = 2;
	}
	else
	{
		i = 0;
	}
	for (; (s[i] >= '0' && s[i] <= '1'); ++i)
	{
		n *= 2;
		n += s[i] - '0';
	}
	return n;
}
